define(['jquery', 'toastr', 'layui'], function ($, Toastr, Layui) {
    var Mon = {
        config: {
            // toastr默认配置
            toastr: {
                "closeButton": true,
                "debug": false,
                "newestOnTop": false,
                "progressBar": false,
                "positionClass": "toast-top-center",
                "preventDuplicates": false,
                "onclick": null,
                "showDuration": "300",
                "hideDuration": "1000",
                "timeOut": "5000",
                "extendedTimeOut": "1000",
                "showEasing": "swing",
                "hideEasing": "linear",
                "showMethod": "fadeIn",
                "hideMethod": "fadeOut"
            }
        },
        events: {
            // 请求成功的回调
            onAjaxSuccess: function (ret, onAjaxSuccess) {
                var data = typeof ret.data !== 'undefined' ? ret.data : null;
                var msg = typeof ret.msg !== 'undefined' && ret.msg ? ret.msg : '操作成功';

                if (typeof onAjaxSuccess === 'function') {
                    var result = onAjaxSuccess.call(this, data, ret);
                    if (result === false) {
                        return;
                    }
                }
                Toastr.success(msg);
            },
            // 请求错误的回调
            onAjaxError: function (ret, onAjaxError) {
                var data = typeof ret.data !== 'undefined' ? ret.data : null;
                if (typeof onAjaxError === 'function') {
                    var result = onAjaxError.call(this, data, ret);
                    if (result === false) {
                        return;
                    }
                }
                Toastr.error(ret.msg);
            },
            // 服务器响应数据后
            onAjaxResponse: function (response) {
                try {
                    var ret = typeof response === 'object' ? response : JSON.parse(response);
                    if (!ret.hasOwnProperty('code')) {
                        $.extend(ret, { code: -2, msg: response, data: null });
                    }
                } catch (e) {
                    var ret = { code: -1, msg: e.message, data: null };
                }
                return ret;
            }
        },
        api: {
            // 页面返回上一页并刷新
            rollback: function () {
                window.location = document.referrer
            },
            // 是否为移动端
            isMoble: function () {
                if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|iPad)/i))) {
                    return true
                }

                return false
            },
            // 获取get参数
            get: function (key, def) {
                var param = document.location.href.split("?");
                var get = {};
                if ("string" == typeof (param[1])) {
                    var pair = param[1].split("&");
                    for (var i in pair) {
                        var j = pair[i].split("=");
                        get[j[0]] = j[1] ? j[1] : "";
                    }
                }
                return key ? (get[key] ? get[key] : def) : get;
            },
            // 实现php urlencode 方法
            urlencode: function (str) {
                var output = '';
                var x = 0;
                str = str.toString();
                var regex = /(^[a-zA-Z0-9-_.\-]*)/;
                while (x < str.length) {
                    var match = regex.exec(str.substr(x));
                    if (match != null && match.length > 1 && match[1] != '') {
                        output += match[1];
                        x += match[1].length;
                    } else {
                        if (str.substr(x, 1) == ' ') {
                            output += '+';
                        }
                        else {
                            var charCode = str.charCodeAt(x);
                            var hexVal = charCode.toString(16);
                            output += '%' + (hexVal.length < 2 ? '0' : '') + hexVal.toUpperCase();
                        }
                        x++;
                    }
                }
                return output;
            },
            // 格式化时间戳
            dateFormat: function (timeStamp, format = 'Y-m-d') {
                var date = new Date(parseInt(timeStamp) * 1000);
                var array_format = format.split('-');
                var dates = [];
                var times = [];
                $.each(array_format, function (i, v) {
                    switch (v) {
                        case 'Y':
                            dates.push(date.getFullYear());
                            break;
                        case 'm':
                            var m = date.getMonth() + 1;
                            m = m < 10 ? '0' + m : m;
                            dates.push(m);
                            break;
                        case 'd':
                            var d = date.getDate();
                            d = d < 10 ? ('0' + d) : d;
                            dates.push(d);
                            break;
                        case 'H':
                            var h = date.getHours();
                            h = h < 10 ? ('0' + h) : h;
                            times.push(h);
                            break;
                        case 'i':
                            var i = date.getMinutes();
                            i = i < 10 ? ('0' + i) : i;
                            times.push(i);
                            break;
                        case 's':
                            var s = date.getSeconds();
                            s = s < 10 ? ('0' + s) : s;
                            times.push(s);
                            break;
                    }
                })
                var res = dates.join('-');
                return (times.length > 0) ? res + ' ' + times.join(':') : res;
            },
            // 格式化日期
            unixFormat: function (dateTime) {
                var date = new Date(dateTime)
                return Math.ceil(date.getTime() / 1000);
            },
            // 发送Ajax请求
            ajax: function (options, success, error) {
                options = typeof options === 'string' ? { url: options } : options;
                var index;
                if (typeof options.loading === 'undefined' || options.loading) {
                    index = Layer.load(options.loading || 2);
                }
                options = $.extend({
                    type: "POST",
                    dataType: "json",
                    success: function (ret) {
                        index && Layer.close(index);
                        ret = Mon.events.onAjaxResponse(ret);
                        if (ret.code === 1) {
                            Mon.events.onAjaxSuccess(ret, success);
                        } else {
                            Mon.events.onAjaxError(ret, error);
                        }
                    },
                    error: function (xhr) {
                        index && Layer.close(index);
                        var ret = { code: xhr.status, msg: xhr.statusText, data: null };
                        Mon.events.onAjaxError(ret, error);
                    }
                }, options);
                $.ajax(options);
            },
            // 修正URL
            fixurl: function (url) {
                return url;
            },
            // 获取修复后可访问的cdn链接
            cdnurl: function (url, domain) {
                var rule = new RegExp("^((?:[a-z]+:)?\\/\\/|data:image\\/)", "i");
                if (domain && !rule.test(url)) {
                    domain = typeof domain === 'string' ? domain : location.origin;
                    url = domain + url;
                }
                return url;
            },
            // 打开一个弹出窗口
            open: function (url, title, options) {
                title = options && options.title ? options.title : (title ? title : "");
                url = Mon.api.fixurl(url);
                url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1";
                var area = [$(window).width() > 800 ? '768px' : '90%', $(window).height() > 680 ? '640px' : '90%'];
                options = $.extend({
                    type: 2,
                    title: title,
                    shadeClose: true,
                    // shade: false,
                    maxmin: true,
                    moveOut: true,
                    scrollbar: false,
                    area: area,
                    content: url,
                    zIndex: Layer.zIndex,
                    success: function (layero, index) {
                        var that = this;
                        // 存储callback事件
                        $(layero).data("callback", that.callback);
                        // $(layero).removeClass("layui-layer-border");
                        Layer.setTop(layero);
                        try {
                            var frame = Layer.getChildFrame('html', index);
                            var layerfooter = frame.find(".layer-footer");
                            Mon.api.layerfooter(layero, index, that);

                            //绑定事件
                            if (layerfooter.length > 0) {
                                // 监听窗口内的元素及属性变化
                                // Firefox和Chrome早期版本中带有前缀
                                var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
                                if (MutationObserver) {
                                    // 选择目标节点
                                    var target = layerfooter[0];
                                    // 创建观察者对象
                                    var observer = new MutationObserver(function (mutations) {
                                        Mon.api.layerfooter(layero, index, that);
                                        // mutations.forEach(function (mutation) {
                                        // });
                                    });
                                    // 配置观察选项:
                                    var config = { attributes: true, childList: true, characterData: true, subtree: true }
                                    // 传入目标节点和观察选项
                                    observer.observe(target, config);
                                    // 随后,你还可以停止观察
                                    // observer.disconnect();
                                }
                            }
                        } catch (e) {
                            console.error(e)
                        }
                        if ($(layero).height() > $(window).height()) {
                            // 当弹出窗口大于浏览器可视高度时,重定位
                            Layer.style(index, {
                                top: 0,
                                height: $(window).height()
                            });
                        }
                    }
                }, options ? options : {});
                if ($(window).width() < 480 || (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && top.$(".tab-pane.active").length > 0)) {
                    options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
                    options.offset = [top.$(".tab-pane.active").scrollTop() + "px", "0px"];
                }
                return Layer.open(options);
            },
            // 关闭窗口并回传数据
            close: function (data) {
                var index = parent.Layer.getFrameIndex(window.name);
                var callback = parent.$("#layui-layer" + index).data("callback");
                // 再执行关闭
                parent.Layer.close(index);
                // 再调用回传函数
                if (typeof callback === 'function') {
                    callback.call(undefined, data);
                }
            },
            layerfooter: function (layero, index, that) {
                var frame = Layer.getChildFrame('html', index);
                var layerfooter = frame.find(".layer-footer");
                if (layerfooter.length > 0) {
                    $(".layui-layer-footer", layero).remove();
                    var footer = $("<div />").addClass('layui-layer-btn layui-layer-footer');
                    footer.html(layerfooter.html());
                    if ($(".row", footer).length === 0) {
                        $(">", footer).wrapAll("<div class='row'></div>");
                    }
                    footer.insertAfter(layero.find('.layui-layer-content'));
                    // 绑定事件
                    footer.on("click", ".btn", function () {
                        if ($(this).hasClass("disabled") || $(this).parent().hasClass("disabled")) {
                            return;
                        }
                        var index = footer.find('.btn').index(this);
                        $(".btn:eq(" + index + ")", layerfooter).trigger("click");
                    });

                    var titHeight = layero.find('.layui-layer-title').outerHeight() || 0;
                    var btnHeight = layero.find('.layui-layer-btn').outerHeight() || 0;
                    // 重设iframe高度
                    $("iframe", layero).height(layero.height() - titHeight - btnHeight);
                }
                // 修复iOS下弹出窗口的高度和iOS下iframe无法滚动的BUG
                if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
                    var titHeight = layero.find('.layui-layer-title').outerHeight() || 0;
                    var btnHeight = layero.find('.layui-layer-btn').outerHeight() || 0;
                    $("iframe", layero).parent().css("height", layero.height() - titHeight - btnHeight);
                    $("iframe", layero).css("height", "100%");
                }
            },
            success: function (options, callback) {
                var type = typeof options === 'function';
                if (type) {
                    callback = options;
                }
                return Layer.msg('操作成功', $.extend({
                    offset: 0, icon: 1
                }, type ? {} : options), callback);
            },
            error: function (options, callback) {
                var type = typeof options === 'function';
                if (type) {
                    callback = options;
                }
                return Layer.msg('操作失败', $.extend({
                    offset: 0, icon: 2
                }, type ? {} : options), callback);
            },
            msg: function (message, url) {
                var callback = typeof url === 'function' ? url : function () {
                    if (typeof url !== 'undefined' && url) {
                        location.href = url;
                    }
                };
                Layer.msg(message, {
                    time: 2000
                }, callback);
            },
            toastr: Toastr,
            layer: window.Layer
        },
        init: function () {
            // 对相对地址进行处理
            // $.ajaxSetup({
            //     beforeSend: function (xhr, setting) {
            //         setting.url = Mon.api.fixurl(setting.url);
            //     },
            // });

            // 获取定义Layer
            Layui.use('layer', function (Layer) {
                Layer.config({
                    skin: 'layui-layer-mon'
                })
                // 将Layer暴露到全局中去
                window.Layer = Layer
            })

            // 绑定ESC关闭窗口事件
            $(window).keyup(function (e) {
                if (e.keyCode == 27) {
                    if ($(".layui-layer").length > 0) {
                        var index = 0;
                        $(".layui-layer").each(function () {
                            index = Math.max(index, parseInt($(this).attr("times")));
                        });
                        if (index) {
                            Layer.close(index);
                        }
                    }
                }
            });
            // 绑定本页面刷新
            document.addEventListener("keydown", function (e) {
                if (e.keyCode == 116) {
                    e.preventDefault();
                    // 当前页面刷新
                    location.reload()
                }
            }, false);

            // 配置Toastr的参数
            Toastr.options = Mon.config.toastr;
            // 将Toastr暴露到全局中去
            window.Toastr = Toastr;
            // 将Mon渲染至全局
            window.Mon = Mon;
        }
    };

    // 默认初始化执行的代码
    Mon.init();
    return Mon;
});
